package eu.ec.ellipcis.integration.ws.endpoint;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ws.server.endpoint.annotation.Endpoint;
import org.springframework.ws.server.endpoint.annotation.PayloadRoot;
import org.springframework.ws.server.endpoint.annotation.RequestPayload;
import org.springframework.ws.server.endpoint.annotation.ResponsePayload;

import com.sun.org.apache.xerces.internal.jaxp.datatype.XMLGregorianCalendarImpl;

import eu.ec.ellipcis.integration.ws.domain.jaxb.AccountBalanceRequest;
import eu.ec.ellipcis.integration.ws.domain.jaxb.AccountBalanceResponse;
import eu.ec.ellipcis.integration.ws.domain.jaxb.ObjectFactory;
import eu.ec.ellipcis.integration.ws.exception.AccountNumberNotFoundException;
import eu.ec.ellipcis.integration.ws.policy.AccountCustomValidation;
import eu.ec.ellipcis.integration.ws.policy.TypedValidationPolicy;


@Endpoint
public class AccountEndpoint {

    /* ---- Constants ---- */
    Log log = LogFactory.getLog(AccountEndpoint.class);

    /* ---- Instance Variables ---- */
    @Autowired
    private AccountCustomValidation<AccountBalanceRequest> validationPolicy = null;

    /* ---- Constructors ---- */

    /* ---- Business Methods ---- */

    @PayloadRoot(
        namespace="http://www.redpill-linpro.com/account-balance-service",
        localPart="accountBalanceRequest")
    @ResponsePayload
    public AccountBalanceRequest findAccountBalance(@RequestPayload AccountBalanceRequest accountBalanceRequest) {

        log.info("AccountEndpoint - Message Arrived");

        final AccountBalanceResponse response;

        if(isRequestValid(accountBalanceRequest)) {
            response = createDummyResponse();
        } else {
            throw new AccountNumberNotFoundException(
                    "Account number " + accountBalanceRequest.getNumber() + " not valid.");
        }

        return accountBalanceRequest;
    }

    private AccountBalanceResponse createDummyResponse() {
        AccountBalanceResponse response = new ObjectFactory().createAccountBalanceResponse();

        response.setBalance(BigDecimal.valueOf(100.50));
        response.setTimestamp(XMLGregorianCalendarImpl.createDateTime(2010, 4, 4, 12, 0, 0));
        return response;
    }

    private boolean isRequestValid(final AccountBalanceRequest accountBalanceRequest) {

        Map<String, TypedValidationPolicy<Object>> validationPolicies = new HashMap<String, TypedValidationPolicy<Object>>();
        validationPolicies.put("accountRequestType", new AccountCustomValidation());
        return (validationPolicies.get("accountRequestType")).validate(accountBalanceRequest);
        //return true;
    }


    /* ---- Getters and Setters ---- */
}
